package com.ponhu.ea2.goodsCenter.provider.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ponhu.ea2.constants.CommonConstant;
import com.ponhu.ea2.dto.PhPropertyValueDto;
import com.ponhu.ea2.entity.PhInventoryPropertyValueMd;
import com.ponhu.ea2.entity.PhMaterialPropertyValueMd;
import com.ponhu.ea2.entity.PhProperty;
import com.ponhu.ea2.enums.PropertyTypeEnum;
import com.ponhu.ea2.enums.ResponseCodeEnum;
import com.ponhu.ea2.goodsCenter.provider.mapper.PhCategoryMapper;
import com.ponhu.ea2.goodsCenter.provider.mapper.PhPropertyMapper;
import com.ponhu.ea2.goodsCenter.provider.utils.CommonUtils;
import com.ponhu.ea2.support.exception.BusinessRuntimeException;
import com.ponhu.ea2.goodsCenter.provider.mapper.PhInventoryPropertyValueMdMapper;
import com.ponhu.ea2.goodsCenter.provider.service.PhInventoryPropertyValueMdService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ponhu.ea2.goodsCenter.provider.service.PhPropertyService;
import com.ponhu.ea2.goodsCenter.provider.service.PhPropertyValueService;
import com.ponhu.ea2.goodsCenter.provider.utils.ProBeanUtils;
import com.ponhu.ea2.vo.PhCategoryLevel3Vo;
import com.ponhu.ea2.vo.PhPropValueEditVo;
import com.ponhu.ea2.vo.PhPropertyEditVo;
import com.ponhu.ea2.vo.PhPropertyVo;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 货品与属性值关系表 服务实现类
 *
 * @author ${author}
 * @since 2021-10-20
 */
@Service
public class PhInventoryPropertyValueMdServiceImpl
        extends ServiceImpl<PhInventoryPropertyValueMdMapper, PhInventoryPropertyValueMd>
        implements PhInventoryPropertyValueMdService {

    @Resource
    private PhPropertyMapper phPropertyMapper;
    @Resource
    private PhCategoryMapper phCategoryMapper;

    @Autowired
    private PhPropertyService phPropertyService;

    /**
     * 根据货品ID查询所有属性及属性值关系
     *
     * @param inventoryId
     * @return
     */
    @Override
    public List<PhInventoryPropertyValueMd> getPropertyValuesByInventoryId(Long inventoryId) {

        LambdaQueryWrapper<PhInventoryPropertyValueMd> queryWrapper = Wrappers
                .lambdaQuery(PhInventoryPropertyValueMd.class)
                .eq(PhInventoryPropertyValueMd::getInventoryId, inventoryId);

        return list(queryWrapper);
    }

    /**
     * 根据货品ID查询所有属性
     *
     * @param inventoryId
     * @return
     */
    @Override
    public List<PhPropertyVo> getPropertyValueList(Long inventoryId) {

        List<PhInventoryPropertyValueMd> mdList = getPropertyValuesByInventoryId(inventoryId);

        List<Long> propIds = mdList.stream().map(PhInventoryPropertyValueMd::getPropertyId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(propIds)) return Lists.newArrayList();

        Map<Long, String> propMap = phPropertyService.listByIds(propIds)
                .stream().filter(prop -> StringUtils.isNotBlank(prop.getSuffixPrompt()))
                .collect(Collectors.toMap(PhProperty::getId, PhProperty::getSuffixPrompt));
        if (MapUtils.isNotEmpty(propMap))
            mdList.stream().forEach(md ->
                    md.setPropertyValue(String.format("%s%s", md.getPropertyValue(),
                            propMap.getOrDefault(md.getPropertyId(), ""))));

        return CommonUtils.packagingPhPropertyVo(mdList);
    }

    /**
     * 根据货品ID查询货品所属类目所有属性及属性值集合
     *
     * @param inventoryId
     * @param categoryId
     * @return
     */
    @Override
    public List<PhPropertyEditVo> getPropertyValueVos(Long inventoryId, Long categoryId) {

        List<PhInventoryPropertyValueMd> inventoryPropertyValues = getPropertyValuesByInventoryId(inventoryId);

        Set<Long> propIdSet = inventoryPropertyValues.stream()
                .map(PhInventoryPropertyValueMd::getPropertyId).collect(Collectors.toSet());
        Set<Long> valueIdSet = inventoryPropertyValues.stream()
                .map(PhInventoryPropertyValueMd::getValueId).collect(Collectors.toSet());
        Map<Long, String> textPropMap = inventoryPropertyValues.stream().collect(
                Collectors.groupingBy(PhInventoryPropertyValueMd::getPropertyId,
                        Collectors.mapping(PhInventoryPropertyValueMd::getPropertyValue, Collectors.joining(","))));

        PhCategoryLevel3Vo phCategoryLevel3Vo = phCategoryMapper
                .getCategoryLevel3VosById(null, null, categoryId).stream().findFirst().get();
        List<Long> categoryIds = Arrays.asList(phCategoryLevel3Vo.getLevel1Id(),
                phCategoryLevel3Vo.getLevel2Id(), phCategoryLevel3Vo.getLevel3Id());

        return phPropertyMapper.getPropValuesByCategoryIds(PropertyTypeEnum.INVENTORY.getCode(), categoryIds)
                .stream().map(propVo -> {
                    propVo.getValueList().stream()
                            .forEach(value -> value.setChecked(valueIdSet.contains(value.getId())));
                    return propVo.setChecked(propIdSet.contains(propVo.getId()))
                            .setText(textPropMap.get(propVo.getId()));
                }).collect(Collectors.toList());
    }

    /**
     * 批量编辑货品相关属性
     *
     * @param inventoryId
     * @param porpList
     */
    @Override
    public void editInventoryProps(Long inventoryId, List<PhPropertyValueDto> porpList) {

        remove(Wrappers.lambdaUpdate(PhInventoryPropertyValueMd.class)
                .eq(PhInventoryPropertyValueMd::getInventoryId, inventoryId));

        if (CollectionUtils.isEmpty(porpList)) {
            return;
        }

        List<PhInventoryPropertyValueMd> propValueMds = porpList.stream().map(prop ->
                ProBeanUtils.copyProperties(prop, PhInventoryPropertyValueMd.class)
                        .setInventoryId(inventoryId)
        ).collect(Collectors.toList());

        if (!saveBatch(propValueMds)) {
            throw new BusinessRuntimeException(ResponseCodeEnum
                    .INVENTORY_PROP_EXCEPTION_800203);
        }
    }

    @Override
    public void deleteDataByInventoryId(Long inventoryId) {
        this.remove(Wrappers.lambdaQuery(PhInventoryPropertyValueMd.class)
                .eq(PhInventoryPropertyValueMd::getInventoryId, inventoryId));
    }

}
